package ext.trace.camera;

import math.region.Ray3;
import math.region.Rect3;
import math.vec2;
import math.vec3;

public class CameraPinhole implements Camera
{
    
    private Rect3 mRect;
    
    private double mFocalLength;
    
    
    public CameraPinhole()
    {
        this.mRect = new Rect3();
        this.mFocalLength = 1.0;
    }
    
    
    public void setOrig(vec3 aOrig)
    {
        this.mRect.mOrig.set(aOrig);
    }
    
    public void setW(vec3 aW)
    {
        this.mRect.mA.set(aW);
    }
    
    public void setH(vec3 aH)
    {
        this.mRect.mB.set(aH);
    }
    
    public void setFocalLength(double aFocalLength)
    {
        this.mFocalLength = aFocalLength;
    }
    
    
    /**
    Generates a ray from an element of R^2. Maps a parameter-space to world-space.
    @param aUV Contained within [0, 1]^2
    @return 
    */
    public Ray3 generate(vec2 aUV)
    {
        aUV.abs();
        vec3 planePt = this.mRect.convertParam_World(aUV);
        vec3 planeCenter = this.mRect.convertParam_World(vec2.HALF);
        vec3 rayDir = this.mRect.crossAB();
        rayDir.norm();
        rayDir.mul(this.mFocalLength);
        rayDir.add(planeCenter);
        rayDir.mul(-1.0);
        rayDir.add(planePt);
        return new Ray3(planePt, rayDir);
    }
    
}
